package net.sf.nlp.segment;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

import net.sf.nlp.segment.util.Utility;

public class Dictionary 
{
	public static final int MAX_CHINESE_CHAR_NUM = 6768;
	public static final String DICTIONARY_PATH = "/segment/";
	
	TrieTreeNode trieDict = new TrieTreeNode();
	
	public Dictionary(String dictFileName)
	{
		this(dictFileName, null);
	}
	
	public Dictionary(String dictFileName, String customerDict)
	{
		load(getClass().getResourceAsStream(dictFileName));
		
		if (customerDict != null)
			loadCustomerDict(getClass().getResourceAsStream(customerDict));
	}
	
	private void load(InputStream is)
	{
		try
		{
			trieDict.clear();
			
			long freq, length, handle;
			String words;
			
			for (int i = 0; i < MAX_CHINESE_CHAR_NUM; i++)
			{
				long wordItemCount = Utility.getLong(is);
				
				String key = Utility.getGB(i);
				TrieTreeNode node = trieDict.getChildByKey(key, true, false);
				
				for (int j = 0; j < wordItemCount; j++)
				{
					freq = Utility.getLong(is);
					length = Utility.getLong(is);
					handle = Utility.getLong(is);
					words = Utility.getString(is, (int)length);
					
					node.addChild(words, handle, freq, false);
				}
			}
			
			is.close();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public TrieTreeNode getTrieTreeNode(String words)
	{
		TrieTreeNode node = trieDict;
		
		if (words == null || words.length() == 0)
			return null;
		
		String key = null;
		for (int i = 0; i < words.length(); i++)
		{
			key = words.substring(i, i + 1);
			
			node = node.getChildByKey(key);
			
			if (node == null)
				break;
		}
		
		return node;
	}
	
	public List<WordItem> getWordItems(String words)
	{
		TrieTreeNode node = getTrieTreeNode(words);
		
		if (node == null)
			return null;
		
		return node.getWordItems();
	}
	
	private void loadCustomerDict(InputStream is)
	{
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		
		int lineNumber = 0;
		String line  = null;
		
		try 
		{
			while ((line = reader.readLine()) != null)
			{
				lineNumber++;
				
				line = line.trim();
				
				if (line.length() == 0 || line.startsWith("#"))
					continue;
				
				line = line.replaceAll("[ \t]{1,}", " ");
				String[] items = line.split(" ");
				
				if (items.length > 2)
					throw new Exception("The customer dictionary is not correct at line " + lineNumber);
				
				String key = items[0].substring(0, 1);
				String words = items[0].substring(1);
				
				TrieTreeNode node = trieDict.getChildByKey(key, true, true);
				node.addChild(words, PosType.NOUN.getTag(), 10000, true);
			}
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
	}
	
	public void saveAsText(String file)
	{
		trieDict.save(file);
	}
}
